package com.ocom.payconfig.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.ocom.common.entity.card.EntityXfMerchantInfo;
import com.ocom.common.entity.payconfig.EntityDishesInfo;
import com.ocom.common.enums.DataSourceEnum;
import com.ocom.common.enums.MasterSlaveEnum;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.utils.StringUtil;
import com.ocom.common.utils.StringUtils;
import com.ocom.common.vo.payconfig.AccountListRVo;
import com.ocom.common.vo.payconfig.FeeAccountRVo;
import com.ocom.common.vo.payconfig.FeeMerchListRVo;
import com.ocom.common.vo.payconfig.FeeMerchRVo;
import com.ocom.mysql.aspect.DataSourceAspect;
import com.ocom.payconfig.dao.IDaoXfMerchantInfo;
import com.ocom.payconfig.service.CompanyInfoService;
import com.ocom.payconfig.service.DishesInfoService;
import com.ocom.payconfig.service.XfMerchantInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class XfMerchantInfoServiceImpl extends ServiceImpl<IDaoXfMerchantInfo, EntityXfMerchantInfo> implements XfMerchantInfoService {


    @Autowired
    private IDaoXfMerchantInfo merchantInfo;

    @Autowired
    CompanyInfoService companyInfoService;

    @Autowired
    DishesInfoService dishesInfoService;

    // 2.7.获取商户信息(getMerchInfo)
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId",isMaster = MasterSlaveEnum.MASTER)
    @Override
    public List<EntityXfMerchantInfo> GetMerchInfo(Long comId, Long merchId, String merchName, Long merchType, Long parentMerchId, Integer page, Integer size) {
        QueryWrapper<EntityXfMerchantInfo> query = Wrappers.query();
        query.select("*","merch_name as feeAccountName");
        query.eq("com_id",comId);
        if (StringUtils.isNotNull(merchId)){
            query.eq("merch_id",merchId);
        }
        if (StringUtils.isNotEmpty(merchName)){
            query.like("merch_name",merchName);
        }
        if (StringUtils.isNotNull(parentMerchId)){
            QueryWrapper<EntityXfMerchantInfo> query1 = Wrappers.query();
            query1.eq("com_id",comId);
            List<EntityXfMerchantInfo> entityXfMerchantInfoOrg = this.list(query1);
            query1.eq("merch_id",parentMerchId);
            List<EntityXfMerchantInfo> parMerchInfo = this.list(query1);

            List<EntityXfMerchantInfo>  childs =  getAllChild(entityXfMerchantInfoOrg,parMerchInfo,0);
            if(childs!=null && childs.size()>0){
                List<Integer> merchIds = childs.stream().map(EntityXfMerchantInfo::getMerchId).collect(Collectors.toList());
                query.in("merch_id",merchIds);
            }
        }
        if (null != merchType){
            List<Long> merchTypes = new ArrayList<>();
            merchTypes.add(merchType);
            if (merchType == 1 || merchType == 2) {
                merchTypes.add(0l);
            }
            query.in("merch_type",merchTypes);
        }
        query.orderByAsc("merch_orgin");
        if(page!=0 && page!=-1){
            PageHelper.startPage(page, size);
        }
        return this.list(query);
    }


    /**
     *
     * @param org
     * @param list
     * @return
     */
    private List<EntityXfMerchantInfo>  getAllChild(List<EntityXfMerchantInfo> org,List<EntityXfMerchantInfo> list,Integer loop) {
        loop++;
        if(loop>=20){
            return list;
        }
        List<EntityXfMerchantInfo> nowList = list;
        Integer beforeSize = nowList.size();
        List<Integer> merchIds = nowList.stream().map(EntityXfMerchantInfo::getMerchId).collect(Collectors.toList());
        for (EntityXfMerchantInfo entityXfMerchantInfo :org){
            if(!merchIds.contains(entityXfMerchantInfo.getMerchId()) && merchIds.contains(entityXfMerchantInfo.getParentMerchId())){
                nowList.add(entityXfMerchantInfo);
            }
        }
        Integer afterSize = nowList.size();

        if(beforeSize.equals(afterSize)){
            return  list;
        }else{
            return  getAllChild(org,nowList,loop);
        }
    }


    //获取一条
    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
    public EntityXfMerchantInfo GetMerchInfo(Long comId, Long merchId) {
        QueryWrapper<EntityXfMerchantInfo> query = Wrappers.query();
        query.eq("com_id",comId);
        query.eq("merch_id",merchId);
        return  this.getOne(query);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
    public List<EntityXfMerchantInfo> getMerchInfoByIds(Long comId, List<Integer> ids) {
        return this.list(Wrappers.lambdaQuery(EntityXfMerchantInfo.class).eq(EntityXfMerchantInfo::getComId,comId).in(EntityXfMerchantInfo::getMerchId,ids));
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "companyId")
    @Override
    public EntityXfMerchantInfo GetMerchInfoById(Long companyId, Integer merchId) {
        QueryWrapper<EntityXfMerchantInfo> query = new QueryWrapper<>();
        query.eq("com_id",companyId);
        query.eq("merch_id",merchId);
        return this.getOne(query);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB)
    @Override
    public EntityXfMerchantInfo GetMerchInfoById(Long companyId ,Long parentMerchId,Long merchId) {
        QueryWrapper<EntityXfMerchantInfo> query = new QueryWrapper<>();
        query.eq("com_id",companyId);
        //0最高級
        query.eq("parent_merch_id",parentMerchId);
        if(merchId!=null && merchId>0l){
            query.eq("merch_id",merchId);
        }
        query.last("limit 1");
        return this.getOne(query);
    }

    // 2.8.判断商户名称是否可用(getMerchInfoByName)
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
    @Override
    public List<EntityXfMerchantInfo> GetMerchInfoByName(Long comId, String merchName) {
        QueryWrapper<EntityXfMerchantInfo> query = Wrappers.query();
        query.eq("com_id",comId);
        query.eq("merch_name",merchName);

        return merchantInfo.selectList(query);
    }
    // 2.9.添加商户信息(addMerchInfo)
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
    @Override
    public EntityXfMerchantInfo AddMerchInfo(Long comId, EntityXfMerchantInfo entityXfMerchantInfo) {
        if(entityXfMerchantInfo.getParentMerchId()==null || entityXfMerchantInfo.getParentMerchId()==0){
            entityXfMerchantInfo.setParentMerchId(0);
            entityXfMerchantInfo.setMerchOrgin(",");
        }
        if(entityXfMerchantInfo.getParentMerchId()!=0){
            //查找父级
            QueryWrapper<EntityXfMerchantInfo> query = Wrappers.query();
            query.eq("com_id",comId);
            query.eq("merch_id",entityXfMerchantInfo.getParentMerchId());
            EntityXfMerchantInfo entityXfMerchantInfo1 = this.getOne(query);
            entityXfMerchantInfo.setMerchOrgin(entityXfMerchantInfo1.getMerchOrgin()+entityXfMerchantInfo1.getMerchId()+",");
        }
        Boolean b = this.save(entityXfMerchantInfo);

        if (entityXfMerchantInfo.getMerchType().equals(3l)) {
            addDishesInfo(comId, entityXfMerchantInfo.getMerchId());
        }

        if(!b) return null;
        return entityXfMerchantInfo;
    }

    // 2.10.修改商户信息(updateMerchInfo)
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
    @Override
    public void UpdateMerchInfo(Long comId, EntityXfMerchantInfo entityXfMerchantInfo) {
        if (entityXfMerchantInfo.getMerchType().equals(3l)) {
            addDishesInfo(comId, entityXfMerchantInfo.getMerchId());
        }
        merchantInfo.updateById(entityXfMerchantInfo);
    }

    private void addDishesInfo(Long comId, Integer merchId){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("comId",comId);
        jsonObject.put("merchId",merchId);
        jsonObject.put("dishesName","音频通话");
        jsonObject.put("dishesCode","voice");

        if (null == dishesInfoService.selectDishesInfo(comId, jsonObject)){
            EntityDishesInfo entityDishesInfo = new EntityDishesInfo();
            entityDishesInfo.setComId(comId);
            entityDishesInfo.setMerchId(merchId);
            entityDishesInfo.setDishesClassId(-1);
            entityDishesInfo.setDishesName("音频通话");
            entityDishesInfo.setDishesCode("voice");
            entityDishesInfo.setSort(1);
            entityDishesInfo.setStatus(Byte.valueOf("1"));

            dishesInfoService.insertDishesInfo(comId, entityDishesInfo);
        }

        jsonObject.put("dishesName","视频通话");
        jsonObject.put("dishesCode","video");
        if (null == dishesInfoService.selectDishesInfo(comId, jsonObject)){
            EntityDishesInfo entityDishesInfo = new EntityDishesInfo();
            entityDishesInfo.setComId(comId);
            entityDishesInfo.setMerchId(merchId);
            entityDishesInfo.setDishesClassId(-1);
            entityDishesInfo.setDishesName("视频通话");
            entityDishesInfo.setDishesCode("video");
            entityDishesInfo.setSort(2);
            entityDishesInfo.setStatus(Byte.valueOf("1"));

            dishesInfoService.insertDishesInfo(comId, entityDishesInfo);
        }

    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
    public Result existMerchanName(Long comId, Long merchId, String merchName) {
        QueryWrapper<EntityXfMerchantInfo> query = Wrappers.query();
        query.eq("com_id",comId);
        query.eq("merch_name",merchName);
        query.ne("merch_id",merchId);
        List<EntityXfMerchantInfo> list=this.list(query);
        if(list!=null && list.size()>0){
            return ResultUtil.error(ResultEnum.Err_3018);
        }else{
            return ResultUtil.success(true);
        }
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "companyId")
    public List<EntityXfMerchantInfo> GetMerchInfo(Long companyId) {
        QueryWrapper<EntityXfMerchantInfo> query = Wrappers.query();
        query.eq("com_id",companyId);
        List<EntityXfMerchantInfo> list=this.list(query);
        if(list ==null) return new ArrayList<>();
        return  list;
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
    @Override
    public EntityXfMerchantInfo selectParentMerchs(Long comId, String strParentMerchs) {
        QueryWrapper<EntityXfMerchantInfo> query = Wrappers.query();
        query.select("GROUP_CONCAT(merch_id) as strParentMerchs");
        query.eq("com_id",comId);
        String[] arr=strParentMerchs.split(",");
        query.in("parent_merch_id",arr);
        return this.getOne(query);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
    @Override
    public List<EntityXfMerchantInfo> getConsMerchReports(Long comId, String merchOrgin) {
        QueryWrapper<EntityXfMerchantInfo> query = Wrappers.query();
        query.eq("com_id",comId);
        if (!merchOrgin.equals("")){
            query.like("merch_orgin",merchOrgin);
        }
        query.orderByAsc("merch_orgin");
        return merchantInfo.selectList(query);
    }

//    @Override
//    public Result GetMerchInfoByMachNo(Long comId, String machNo) {
//        MachMerchPointInfoVo machMerchPointInfo;
//
//        EntityCompanyInfo entityCompanyInfo = companyInfoService.GetCompanyInfo(comId);
//        if(entityCompanyInfo==null){
//            return ResultUtil.error(ResultEnum.Err_301);
//        }
//        MachMerchPointInfoVo machMerchPointInfoVo = merchantInfo.getMerchPointInfo(comId,machNo);
//        machMerchPointInfoVo.setCompanyName(entityCompanyInfo.getComName());
//        if(machMerchPointInfoVo.getMerchId()==0){
//            machMerchPointInfoVo.setMerchName(entityCompanyInfo.getComName());
//        }
//        return ResultUtil.success(machMerchPointInfoVo);
//    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
    public Boolean AddXfMerchantInfo(Long comId, EntityXfMerchantInfo entityXfMerchantInfo) {
//        LocalDateTime date = LocalDateTime.now();
//        entityXfMerchantInfo.setCreateTime(date);
//        entityXfMerchantInfo.setUpdateTime(date);
        return this.save(entityXfMerchantInfo);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
    public EntityXfMerchantInfo exitsMerchantName(Long comId, String merchName){
        QueryWrapper<EntityXfMerchantInfo> query = Wrappers.query();
        query.select("merch_id");
        query.eq("com_id",comId);
        query.eq("merch_name",merchName);
        query.last("LIMIT 1");
        EntityXfMerchantInfo info = this.getOne(query);
        return info;
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
    public Result getAllAccount(Long comId) {
        QueryWrapper<EntityXfMerchantInfo> query = Wrappers.query();
        query.select("merch_id AS feeAccountId", "merch_name AS feeAccountName", "remark");
        query.eq("com_id",comId);
        query.eq("fee_flag",1);
        List<Map<String,Object>> list = this.listMaps(query);
        Map<String,Object> mapListInfo = new HashMap<>();
        mapListInfo.put("accountList",list);
        return ResultUtil.success(mapListInfo);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
    public AccountListRVo getFeeAccountList(Long comId) {
        List<FeeAccountRVo> list = merchantInfo.getFeeAccount(comId);
        AccountListRVo accountListRVo = new AccountListRVo();
        accountListRVo.setAccountRVoList(list);
        return accountListRVo;
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
    public FeeMerchListRVo getFeeMerchList(Long comId) {
        List<FeeMerchRVo> list = merchantInfo.getFeeMerch(comId);
        FeeMerchListRVo feeMerchListRVo = new FeeMerchListRVo();
        feeMerchListRVo.setFeeMerchRVoList(list);
        return feeMerchListRVo;
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
    public Result updateMerchInfo(Long comId, EntityXfMerchantInfo request){
        if(request.getFeeAccountId() != null && request.getFeeAccountId()!= 0){
            request.setMerchId(request.getFeeAccountId());
        }
        boolean bInfo = this.updateById(request);
        if(bInfo){
            return ResultUtil.success(bInfo);
        }
        return ResultUtil.error(ResultEnum.Err_3026);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "comId")
    public Result changeMerchStatus(Long comId,int merchId){
        UpdateWrapper update = Wrappers.update();
        update.eq("com_id",comId);
        update.eq("merch_id",merchId);
        update.setSql("fee_flag = 1 - fee_flag");
        boolean bStatus = this.update(update);
        if(bStatus){
            return ResultUtil.success();
        }
        return ResultUtil.error(ResultEnum.Err_3026);
    }

}
